import math
from OpenGL.GL import *  # glSomething
from OpenGL.GLU import * # gluSomething

class Camera:
	def __init__(self,x,y,z,a,h=0):
		self.x = x
		self.y = y
		self.z = z
		self.ux = 0
		self.uy = 1
		self.uz = 0
		self.a = a
		self.h = h
		self.update_vel()

	def lookat(self):
		glMatrixMode(GL_MODELVIEW)
		glLoadIdentity()
		gluLookAt(self.x,self.y,self.z,self.x+self.dx,self.y+self.dy,self.z+self.dz,self.ux,self.uy,self.uz)

	def update_vel(self):
		ch = math.cos(self.h)
		self.dx = math.cos(self.a)*ch
		self.dz = math.sin(self.a)*ch
		self.dy = math.sin(self.h)
		
	def point_at(self,x,y,z):
		""" point camera at given location """
		dx = x - self.x
		dy = y - self.y
		dz = z - self.z	

		l = math.sqrt(dx*dx + dz*dz)
		self.a = math.atan2(dx/l,dz/l)

		ll = math.sqrt(l*l + dy*dy)
		self.h = math.atan2(dy/ll,l/ll)
		self.update_vel()
		print self.dx, self.dy, self.dz

	def steer(self,da):
		self.a+=da
		if self.a>math.pi*2:
			self.a -= math.pi*2
		if self.a<0:
			self.a+= math.pi*2
		self.update_vel()
	
	def pitch(self,dh):
		self.h+=dh
		if self.h>math.pi/2.1:
			self.h = math.pi/2.1
		if self.h<-math.pi/2.1:
			self.h = - math.pi/2.1
		self.update_vel()
	
	def lift(self,dy):
		self.y += dy
	
	def forward(self,l):
		self.x+=self.dx*l
		self.y+=self.dy*l
		self.z+=self.dz*l
	
	def drawcursor(self):
		x = self.x + self.dx*3
		y = self.y + self.dy*3
		z = self.z + self.dz*3
		
		glBegin(GL_TRIANGLES)
		glColor(0.5,0,0)
		glVertex(x,y,z)
		glVertex(x,y+0.1,z)
		glVertex(x,y,z+0.2)
		glEnd()

	def addcube(self,what):
		if self.dy>-0.1:
			return
		t = - self.y / self.dy
		self.curx = self.x + t* self.dx
		self.curz = self.z + t* self.dz
		xx = int(self.curx)
		yy = int(self.curz)
		if (0<= xx < SX) and (0<= yy < SY):
			field[xx,yy] = what
	
	def point_at_cube(self,x1,y1,z1,x2,y2,z2):
		if abs(self.dx)>= max(abs(self.dy),abs(self.dz)): # go throught x axis
			t = (x1 - self.x)/self.dx
			py = self.y + t*self.dy
			pz = self.z + t*self.dz

			if (y1 < py < y2) and (z1 < pz < z2):
				return True

			t = (x2 - self.x)/self.dx
			py = self.y + t*self.dy
			pz = self.z + t*self.dz

			if (y1 < py < y2) and (z1 < pz < z2):
				return True
			return False
		if abs(self.dy)> max(abs(self.dx),abs(self.dz)): # go throught y axis
			'''s/x/temp/g s/y/x/g s/temp/y/g'''
			t = (y1 - self.y)/self.dy
			px = self.x + t*self.dx
			pz = self.z + t*self.dz

			if (x1 < px < x2) and (z1 < pz < z2):
				return True

			t = (y2 - self.y)/self.dy
			px = self.x + t*self.dx
			pz = self.z + t*self.dz

			if (x1 < px < x2) and (z1 < pz < z2):
				return True
			return False
		if abs(self.dz)> max(abs(self.dy),abs(self.dx)): # go throught x axis
			'''s/x/temp/g s/z/x/g s/temp/z/g'''
			t = (z1 - self.z)/self.dz
			py = self.y + t*self.dy
			px = self.x + t*self.dx

			if (y1 < py < y2) and (x1 < px < x2):
				return True

			t = (z2 - self.z)/self.dz
			py = self.y + t*self.dy
			px = self.x + t*self.dx

			if (y1 < py < y2) and (x1 < px < x2):
				return True
			return False

